package com.dream.web.utils;

import com.dream.web.config.QiNiuConfig;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;


@Component
public class QiNiuUtils {
    private String generateToken() {
        Auth auth = Auth.create(QiNiuConfig.getAccesskey(), QiNiuConfig.getSecretKey());
        return auth.uploadToken(QiNiuConfig.getBucketName());
    }

    /**
     * 根据spring mvc 文件接口上传
     *
     * @param multipartFile spring mvc 文件接口
     * @return 文件路径
     */

    public String uploadFile(MultipartFile multipartFile) throws FileUploadException {
        byte[] bytes = getBytesWithMultipartFile(multipartFile);
        return this.uploadFile(bytes);
    }

    /**
     * 根据spring mvc 文件接口上传
     *
     * @param data 文件
     * @return 文件路径
     */

    public String uploadFile(byte[] data) throws FileUploadException {
        return this.uploadFile(data, null, null);
    }


    /**
     * 根据spring mvc 文件接口上传
     *
     * @param data     文件
     * @param fileName 文件名
     * @param filePath 文件前缀,例如:/test或者/test/
     * @return 文件路径
     */

    public String uploadFile(byte[] data, String fileName, String filePath) throws FileUploadException {
        String key = preHandle(fileName, filePath);
        Response response;
        try {
            //构造一个带指定Zone对象的配置类
            Configuration cfg = new Configuration(Zone.zone0());
            UploadManager uploadManager = new UploadManager(cfg);
            response = uploadManager.put(data, key, generateToken());
        } catch (QiniuException e) {
            throw new FileUploadException(e.getMessage());
        }
        return this.getUrlPath(response);
    }

    private byte[] getBytesWithMultipartFile(MultipartFile multipartFile) {
        try {
            return multipartFile.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    private String preHandle(String fileName, String filePath) throws FileUploadException {
        if (StringUtils.isNotBlank(fileName) && !fileName.contains(".")) {
            throw new FileUploadException("文件名必须包含尾缀");
        }
        if (StringUtils.isNotBlank(filePath) && !filePath.startsWith("/")) {
            throw new FileUploadException("前缀必须以'/'开头");
        }
        String name = StringUtils.isBlank(fileName) ? RandomStringUtils.randomAlphanumeric(32) : fileName;
        if (StringUtils.isBlank(filePath)) {
            return name;
        }
        String prefix = filePath.replaceFirst("/", "");
        return (prefix.endsWith("/") ? prefix : prefix.concat("/")).concat(name);
    }


    private String getUrlPath(Response response) throws FileUploadException {
        if (!response.isOK()) {
            throw new FileUploadException("文件上传失败");
        }
        DefaultPutRet defaultPutRet;
        try {
            defaultPutRet = response.jsonToObject(DefaultPutRet.class);
        } catch (QiniuException e) {
            throw new FileUploadException(e.getMessage());
        }
        String key = defaultPutRet.key;
        if (key.startsWith(QiNiuConfig.getBucketHostName())) {
            return key;
        }
        return QiNiuConfig.getBucketHostName() + (key.startsWith("/") ? key : "/" + key);
    }

}
